/************************************************************
 * Project Name         [Thinking_In_Java]
 * File Name            [GobangFrame.java]
 * Creation Date        [22-Jul-2014]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ************************************************************/
package pkg_03_game.gobang.version_3;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

/**
 * 五子棋
 * 
 * @author 不落的太阳(Sean Yang)
 * @version 1.0
 * @since JDK 6
 * 
 */
public class GobangFrame extends JFrame implements MouseListener {

	private static final long serialVersionUID = -1577909846839439518L;
	// 获得屏幕的宽和高
	private static final int SCREEN_WIDTH = Toolkit.getDefaultToolkit()
			.getScreenSize().width;
	private static final int SCREEN_HEIGHT = Toolkit.getDefaultToolkit()
			.getScreenSize().height;

	// 棋子的位置坐标
	private int x, y;

	// 保存之前下过的全部棋子——棋盘上的点一共 19 * 19
	// 数组中0表示该位置无棋子, 1表示该位置为黑子, 2表示该位置为白子
	private final int[][] allChess = new int[19][19];

	// 黑方先行
	private boolean isBlack = true;

	// 是否继续
	private boolean isContinue = true;

	/**
	 * 绘制棋盘
	 */
	@Override
	public void paint(Graphics g) {
		try {
			BufferedImage image = ImageIO.read(GobangFrame.class
					.getClassLoader().getResourceAsStream(
							"pkg_03_game/gobang/images/gobang.jpg"));
			g.drawImage(image, 0, 25, this);
		} catch (Exception e) {
			e.printStackTrace();
		}

		// 画出棋盘, 19 * 19的棋盘, 横纵间隔大概为360pix, 分为18份
		for (int i = 0; i < 19; i++) {
			g.drawLine(10, 75 + 20 * i, 370, 75 + 20 * i);
			g.drawLine(10 + 20 * i, 75, 10 + 20 * i, 435);
		}

		// 绘制九宫点
		Color color = g.getColor();
		g.setColor(Color.YELLOW);
		g.fillOval(67, 133, 6, 6);
		g.fillOval(307, 133, 6, 6);
		g.fillOval(67, 373, 6, 6);
		g.fillOval(307, 373, 6, 6);
		g.fillOval(67, 252, 6, 6);
		g.fillOval(307, 252, 6, 6);
		g.fillOval(187, 133, 6, 6);
		g.fillOval(187, 373, 6, 6);
		g.fillOval(187, 252, 6, 6);
		g.setColor(color);

		// 设置相应的显示信息
		g.setFont(new Font("隶书", Font.PLAIN, 20));
		g.drawString("游戏信息", 80, 60);

		g.drawString("黑方时间: 无限制", 50, 475);
		g.drawString("白方时间: 无限制", 270, 475);

		// 绘制棋子
		for (int i = 0; i < 19; i++) {
			for (int j = 0; j < 19; j++) {
				// 绘制黑子
				if (allChess[i][j] == 1) {
					int tempX = i * 20 + 10;
					int tempY = j * 20 + 75;
					g.fillOval(tempX - 4, tempY - 4, 10, 10);
				}
				// 绘制白子(白底黑边)
				if (allChess[i][j] == 2) {
					int tempX = i * 20 + 10;
					int tempY = j * 20 + 75;
					g.setColor(Color.WHITE);
					g.fillOval(tempX - 4, tempY - 4, 10, 10);
					g.setColor(Color.BLACK);
					g.drawOval(tempX - 4, tempY - 4, 10, 10);
				}
			}
		}
	}

	private void init() {
		setTitle("五子棋");
		this.setSize(495, 500);
		this.setLocation((SCREEN_WIDTH - 500) / 2, (SCREEN_HEIGHT - 500) / 2);
		addMouseListener(this);

	}

	public GobangFrame() {
		super();
		init();
	}

	@Override
	public void mouseClicked(MouseEvent e) {

	}

	@Override
	public void mouseEntered(MouseEvent e) {

	}

	@Override
	public void mouseExited(MouseEvent e) {

	}

	@Override
	public void mousePressed(MouseEvent e) {
		x = e.getX();
		y = e.getY();
		if (isContinue) {
			// 确认落子在棋盘内
			if (x >= 10 && x < 370 && y > 75 && y <= 435) {
				// 判断交叉点
				x = (x - 10) / 20;
				y = (y - 75) / 20;

				if (allChess[x][y] == 0) {
					if (isBlack) {
						allChess[x][y] = 1;
						isBlack = false;
					} else {
						allChess[x][y] = 2;
						isBlack = true;
					}
					// 每次落子之后检查
					if (isWin()) {
						JOptionPane.showMessageDialog(this, "游戏结束"
								+ (allChess[x][y] == 1 ? "黑方" : "白方") + "获胜");
						isContinue = false;
					}
				} else {
					JOptionPane.showMessageDialog(this, "当前位置有棋子请重新落子");
				}
				this.repaint();
			}
		}
	}

	@Override
	public void mouseReleased(MouseEvent e) {

	}

	/**
	 * 判断胜负
	 * 
	 * @return
	 */
	private boolean isWin() {
		boolean isWin = false;

		// 保存有多少同色的棋子相连
		int counter = 1;

		int i = 1;
		int color = allChess[x][y];

		while (color == allChess[x + i][y]) {// 横向判断
			++counter;
			i++;
		}
		i = 1;
		while (color == allChess[x - i][y]) {// 横向判断
			++counter;
			i++;
		}
		i = 1;

		while (color == allChess[x][y + i]) {// 纵向判断
			++counter;
			i++;
		}
		i = 1;
		while (color == allChess[x][y - i]) {// 纵向判断
			++counter;
			i++;
		}
		i = 1;

		while (color == allChess[x + i][y + i]) {// 右下判断
			++counter;
			i++;
		}
		i = 1;
		while (color == allChess[x + i][y - i]) {// 右上判断
			++counter;
			i++;
		}
		i = 1;
		while (color == allChess[x - i][y + i]) {// 左下判断
			++counter;
			i++;
		}
		i = 1;
		while (color == allChess[x - i][y - i]) {// 左上判断
			++counter;
			i++;
		}

		if (counter >= 5) {
			isWin = true;
		}

		return isWin;
	}

}
